package com.booter.ws.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

/**
 * NIO方式相比BIO方式效率更高且消耗更少，
 * BIO方式一旦连接数过多，Tomcat会出内存泄露继而引起崩溃的问现。内存溢出是由于建立了过多的线程引起的。
 * JDK5.0以后缺省的线程堆栈大小为1M，缺省的线程数是200。maxConnections调整的非常大时BIO方式线程占用内存的量也会非常大无法承载更多的连接。因此Tomcat使用NIO的连接方式是非常必要的。
 */
@Slf4j
@Component
class CustomTomcatConnectorCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        ((TomcatServletWebServerFactory) factory).setProtocol("org.apache.coyote.http11.Http11Nio2Protocol");
        ((TomcatServletWebServerFactory) factory).addConnectorCustomizers(new org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                ProtocolHandler protocol = connector.getProtocolHandler();
                log.info("Tomcat({})  -- MaxConnection:{};MaxThreads:{};MinSpareThreads:{}", //
                        protocol.getClass().getName(), //
                        ((AbstractHttp11Protocol<?>) protocol).getMaxConnections(), //
                        ((AbstractHttp11Protocol<?>) protocol).getMaxThreads(), //
                        ((AbstractHttp11Protocol<?>) protocol).getMinSpareThreads());
            }
        });
    }
}
